﻿using System;
using System.Drawing;
using System.IO;
using System.Net.Mime;
using System.Web;
using System.Web.Hosting;
using EPiServer.ImageLibrary;
using EPiServer.Security;
using EPiServer.Web;
using EPiServer.Web.Hosting;

namespace EPiServer.Labs.MobilePack.Core.Helpers
{
    public static class ImageHelper
    {
        public static void CacheImage(byte[] imageBuffer, string fileName)
        {
            string virtualImageCacheName = MobilePackSection.CurrentSection.VirtualImageCacheName;

            if (String.IsNullOrEmpty(virtualImageCacheName))
            {
                return;
            }

            var provider = (VirtualPathUnifiedProvider)VirtualPathHandler.GetProvider(MobilePackSection.CurrentSection.VirtualImageCacheName);

            var rootFolder = (UnifiedDirectory)provider.GetDirectory(provider.VirtualPathRoot);

            rootFolder.BypassAccessCheck = true;
            UnifiedFile image = rootFolder.CreateFile(fileName);

            IVersioningFile versioningFile;

            if (image.TryAsVersioningFile(out versioningFile))
            {
                if (!versioningFile.IsCheckedOut)
                {
                    versioningFile.CheckOut();
                }

                using (Stream stream = image.Open(FileMode.Create, FileAccess.Write))
                {
                    stream.Write(imageBuffer, 0, imageBuffer.Length);
                }

                versioningFile.CheckIn("Cached image by MobilePack");
            }
        }

        public static bool IsImageRequest(string filename)
        {
            filename = filename.ToLower();

            return filename.EndsWith(".jpg") || filename.EndsWith(".jpeg");
        }

        public static bool CacheImageExists(string fileName)
        {
            string virtualImageCacheName = MobilePackSection.CurrentSection.VirtualImageCacheName;

            if (string.IsNullOrEmpty(virtualImageCacheName))
            {
                return false;
            }

            var provider = (VirtualPathUnifiedProvider)VirtualPathHandler.GetProvider(virtualImageCacheName);

            var rootFolder = (UnifiedDirectory)provider.GetDirectory(provider.VirtualPathRoot);

            string virtualPath = VirtualPathUtilityEx.Combine(rootFolder.VirtualPath, fileName);

            var file = HostingEnvironment.VirtualPathProvider.GetFile(virtualPath) as UnifiedFile;

            if (file == null)
            {
                return false;
            }

            file.BypassAccessCheck = true;

            using (Stream fileStream = file.Open())
            {
                string imageMimeType = MediaTypeNames.Image.Jpeg;

                HttpContext.Current.Response.ContentType = imageMimeType;
                HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);

                byte[] originalImage = new byte[fileStream.Length];

                fileStream.Read(originalImage, 0, (int)fileStream.Length);

                HttpContext.Current.Response.OutputStream.Write(originalImage, 0, originalImage.Length);

                return true;
            }
        }

        public static void ResizeImage(string imageVirtualPath, string widthFromClient)
        {
            int width;
            int height;

            imageVirtualPath = HttpUtility.UrlDecode(imageVirtualPath);

            if (!int.TryParse(widthFromClient, out width))
            {
                // default width
                width = 320;
            }

            var file = VirtualPathHandler.Instance.GetFile(imageVirtualPath, true) as UnifiedFile;

            if (file == null)
            {
                return;
            }

            file.BypassAccessCheck = false;

            if (!file.QueryDistinctAccess(AccessLevel.Read))
            {
                return;
            }

            using (Stream fileStream = file.Open())
            {
                Image image = Image.FromStream(fileStream);

                if (image.Width <= width)
                {
                    return;
                }

                string fileName = string.Format("{0}_{1}{2}", imageVirtualPath.GetHashCode(), width, Path.GetExtension(imageVirtualPath));

                if (CacheImageExists(fileName))
                {
                    HttpContext.Current.Response.End();
                    return;
                }

                height = image.Height * width / image.Width;

                ImageOperation[] operations = new ImageOperation[]
                                              {
                                                  new ImageOperation(ImageEditorCommand.Resize, width, height)
                                              };

                float zoomFactor = 1f;

                string imageMimeType = MediaTypeNames.Image.Jpeg;

                int jpegQuality = 80;

                var imageService = new ImageServiceClient("ImageServiceClientEndPoint");

            
                byte[] originalImage = new byte[fileStream.Length];

                fileStream.Read(originalImage, 0, (int)fileStream.Length);

                byte[] imageBuffer = imageService.RenderImage(originalImage, operations, imageMimeType, zoomFactor, jpegQuality);

                CacheImage(imageBuffer, fileName);

                HttpContext.Current.Response.ContentType = imageMimeType;
                HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
                HttpContext.Current.Response.OutputStream.Write(imageBuffer, 0, imageBuffer.Length);
                HttpContext.Current.Response.End();
            }
        }
    }
}
